package com.dstats;


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.adapter.MatchsAdapter;
import com.entities.Match;
import com.entities.MatchDetailed;
import com.entities.Statistics;
import com.entities.SteamUser;
import com.fetch.Fetch;
import com.fetch.FetchImage;
import com.fetch.FetchMatchsDetails;
import com.fetch.JSONParser;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;

public class MatchsActivity extends FragmentActivity {
	  
		public static final String PREFS_NAME = "statsPrefs";
		
		private static final String accIdSaved = "accId";
	  
		private static final int MENU_SAVE = Menu.FIRST;
		private static final int MENU_GO_BACK = Menu.FIRST+1;
		
	  	private ListView listView;
		private ProgressDialog pDialog;
		private Button load;
		private TextView wins;
		private TextView losses;
		private TextView percentage;
		private TextView totalMatchs;
		private TextView totalKills;
		private TextView totalDeaths;
		private TextView avgGPM;
		private TextView avgXPM;
		private TextView heroDamage;
		private TextView towerDamge;
		private TextView heroHeal;
		private TextView lh;
		private TextView denies;
		private TextView avgLvl;
		private TextView totalGold;
		private TextView kda;
		private ProgressBar pBar;
		
		private Statistics stats;
		private MatchsAdapter matchsAdapter;
		private List<Match> matchList;
		private final int quantityToFetch = 50;
		private boolean dontStartActivity = true;
	  
	  private String getAccId() {/*
		  if(accId!=null && !accId.isEmpty()){
			  return accId;
		  } else {
			  SharedPreferences settings = this.getSharedPreferences(PREFS_NAME, 0);
				 String accSaved = settings.getString(accIdSaved, "");
				 if(accSaved.isEmpty()){
					 onBackPressed();
				 }
				 return accSaved;
				 }*/
		  return getIntent().getStringExtra("accId");
		  
		
	}

	  
	  private FragmentActivity getThisActivity(){
	  		return this;
	  }	    
	private void setAdapterAndListener(List<Match> newMatchList){

		if(newMatchList != null){
			if(matchList==null) matchList = new ArrayList<Match>();
			this.matchList.addAll(newMatchList);
			if(matchsAdapter==null){
			matchsAdapter = new MatchsAdapter(getApplicationContext(), matchList, getAccId());
			
			listView.setAdapter(matchsAdapter);
			} 
			matchsAdapter.notifyDataSetChanged();
			try {
				updateStats(getAccId());
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		} else {
			new FetchMatchs(getAccId(), 0, quantityToFetch).execute();
		}
		
		
		
	}

	private OnItemClickListener onClickOpenMatchDetailed() {
		return new OnItemClickListener() {
	
			@Override
			public void onItemClick(final AdapterView<?> adapter, View arg1, final int arg2,
					long arg3) {
					dontStartActivity = false;
					Long match_id = ((Match) adapter.getItemAtPosition(arg2)).getMatch_id();
					MatchDetailed matchDetailed = MatchDetailed.allMatchsDetailed.get(match_id);
					if(matchDetailed==null){
					new FetchMD(String.valueOf(match_id)).execute();
					} else {
					new StartDetailedMatch(matchDetailed).execute();
						
					}
				
			}
		};
	}


	private OnClickListener onClickLoadNext() {
		return new OnClickListener() {
			
			@Override
			public void onClick(View v) {
			   dontStartActivity = false;
				new FetchMatchs(getAccId(), matchList.get(matchList.size()-1).getMatch_id(), quantityToFetch + 1).execute();	
				matchList.remove(matchList.size()-1);
				
			}
		
		};
	}
	
	@Override
	protected void onResume() {
		super.onResume();
        mAdView.resume();
		pBar.setVisibility(View.INVISIBLE);
		if(matchList!=null){
			dontStartActivity = true;
			new FetchDetailedMatchList(matchList, getAccId()).execute();
		}
		if(pDialog!=null) {
			pDialog.dismiss();
		}
	}
	
	@Override
	protected void onRestart() {
		super.onRestart();
		pBar.setVisibility(View.INVISIBLE);
		if(matchList!=null){
			dontStartActivity = true;
			new FetchDetailedMatchList(matchList, getAccId()).execute();
		}
		if(pDialog!=null) {
			pDialog.dismiss();
		}
	}
	
	private String stringValueInK(int value){
		
		String valueString = String.valueOf(value);
		if(value/1000 >= 1 ){
			if(value/100 - value/1000*10 !=0){
				valueString = String.valueOf(value/1000) + "." + String.valueOf(value/100 - value/1000*10 ) + "k";	
			} else {
				valueString = String.valueOf(value/1000) + "k";	
			}	
		}
		return valueString;
	}
	
	private void updateStats(String accId) throws Exception{
		try {
			stats = new Statistics(matchList, accId);
		} catch (Exception e) {
			stats = new Statistics(matchList, getAccId());
		}

		wins.setText(String.valueOf(stats.getWins()));
		wins.setTextColor(Color.GREEN);
		losses.setText(String.valueOf(stats.getLosses()));
		losses.setTextColor(Color.RED);
		totalMatchs.setText(String.valueOf(stats.getTotalgames()) + " " + getString(R.string.matchs));
		DecimalFormat df = new DecimalFormat("0.00");  
		percentage.setText(String.valueOf(df.format(stats.getPercentage())) +"%");
		totalKills.setText(String.valueOf((int) stats.getKills()) + " " + getString(R.string.kills));
		totalDeaths.setText(String.valueOf((int) stats.getDeaths()) + " " + getString(R.string.deaths));
		avgGPM.setText(String.valueOf((int)(stats.getAvgGpm())) + " " + getString(R.string.gpm));
		avgXPM.setText(String.valueOf((int)(stats.getAvgXpm())) + " " + getString(R.string.xpm));
		heroDamage.setText(stringValueInK((int)(stats.getHero_damage())) + " " + getString(R.string.heroDMG));
		towerDamge.setText(stringValueInK((int)(stats.getTower_damage())) + " " + getString(R.string.towerDMG));
		heroHeal.setText(stringValueInK((int) stats.getHero_healing()) + " " + getString(R.string.heroHEAL));
		lh.setText(String.valueOf((int) stats.getLast_hits()) + " " + getString(R.string.last_hits));
		denies.setText(String.valueOf((int) stats.getDenies()) + " " + getString(R.string.denies));
		avgLvl.setText(String.valueOf(df.format(stats.getAvgLevel())) + " " + getString(R.string.level));
		totalGold.setText(stringValueInK((int)(stats.getGold() + stats.getGold_spent())) + " " + getString(R.string.total) + " " + getString(R.string.gold));
		float kDA = (stats.getKills() + stats.getAssists())/stats.getDenies();
		kda.setText(String.valueOf(df.format(kDA)) + " " + getString(R.string.kda));
		
	}
	    
	
	
	private AdView mAdView;


    @Override
    protected void onPause() {
        mAdView.pause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        mAdView.destroy();
        super.onDestroy();
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.matchs_layout);
        mAdView = (AdView) findViewById(R.id.adViewMatchs);
        mAdView.loadAd(new AdRequest.Builder().build());
		String title = getIntent().getStringExtra("title");
		if(title==null || title.isEmpty()){
			this.setTitle("");
			new GetSteamUserAndSetTitle(getAccId()).execute();
		} else {
			String avatarUrl =  getIntent().getStringExtra("avatarUrl");
			new FetchSteamUserImage(avatarUrl).execute();
			this.setTitle(title);
		}
        dontStartActivity = true;
        listView = (ListView) findViewById(R.id.ListViewMatchs);
        load = new Button(this);
		load.setText(getString(R.string.loadMore));
		listView.addFooterView(load);
		wins = (TextView) findViewById(R.id.textViewWins);
		losses = (TextView) findViewById(R.id.textViewLosses);
		percentage = (TextView) findViewById(R.id.textViewPercentage);
		totalMatchs = (TextView) findViewById(R.id.textViewMatchs);
		load.setOnClickListener(onClickLoadNext());
		totalKills = (TextView) findViewById(R.id.textViewTotalKills);
		totalDeaths = (TextView) findViewById(R.id.textViewTotalDeaths);
		avgGPM = (TextView) findViewById(R.id.textViewGPMAvg);
		avgXPM = (TextView) findViewById(R.id.textViewXPMAvg);
		heroDamage = (TextView) findViewById(R.id.textViewHeroDMG);
		towerDamge = (TextView) findViewById(R.id.textViewTowerDMG);
		heroHeal = (TextView) findViewById(R.id.textViewHeroHeal);
		lh = (TextView) findViewById(R.id.textViewLastHits);
		denies = (TextView) findViewById(R.id.textViewDenies);
		avgLvl = (TextView) findViewById(R.id.textViewLevelAvg);
		totalGold = (TextView) findViewById(R.id.textViewTotalGold);
		kda = (TextView) findViewById(R.id.textViewKDA);
		listView.setOnItemClickListener(onClickOpenMatchDetailed());
		pBar = (ProgressBar) findViewById(R.id.progressBarFetchingMatchs);
		pBar.setVisibility(View.INVISIBLE);
		if(matchList!=null){
			dontStartActivity = true;
			new FetchDetailedMatchList(matchList, getAccId()).execute();
		}
		wins.setText("");
		losses.setText("");
		totalMatchs.setText("");  
		percentage.setText("");
		totalKills.setText("");
		totalDeaths.setText("");
		avgGPM.setText("");
		avgXPM.setText("");
		heroDamage.setText("");
		towerDamge.setText("");
		heroHeal.setText("");
		lh.setText("");
		denies.setText("");
		avgLvl.setText("");
		totalGold.setText("");
		kda.setText("");
		
		setAdapterAndListener(matchList);
		
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	menu.add(Menu.NONE, MENU_SAVE, Menu.NONE, getString(R.string.save_user));
		menu.add(Menu.NONE, MENU_GO_BACK, Menu.NONE, getString(R.string.go_back));
    	return super.onCreateOptionsMenu(menu);
    }
    
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	        case MENU_SAVE:
	        	SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
         	   SharedPreferences.Editor editor = settings.edit();
			     editor.putString(accIdSaved, getAccId());
			     editor.commit();
	            return true;
	        case MENU_GO_BACK:
	        	startActivity(new Intent(getApplicationContext(), MainActivity.class));
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}
    
    private class GetSteamUserAndSetTitle extends Fetch {

    	 private final String url = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/";
		 private final long convertTo64Bits =  Long.valueOf("76561197960265728");
		 private String userId;
		
			
		 public GetSteamUserAndSetTitle(String userId) {
				 this.userId = String.valueOf(convertTo64Bits + Long.valueOf(userId));
			}
			
			@Override
			protected List<NameValuePair> getParams() {
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				params.add(new BasicNameValuePair(Constants.KEY, Constants.apiKey));
				params.add(new BasicNameValuePair(Constants.STEAMIDS, userId));

				return params;
			}

			@Override
			protected String getUrl() {
				return url;
			}
    	
			@Override
			protected void onPostExecute(JSONObject result) {
				super.onPostExecute(result);
				try {
					SteamUser steamUser = new SteamUser(result.getJSONObject("response").getJSONArray("players").getJSONObject(0));
					String personaname = steamUser.getPersonaname();
					getThisActivity().setTitle(personaname);
					
					new FetchSteamUserImage(steamUser.getAvatarUrl()).execute();
					
				} catch (JSONException e) {
					setTitle("Player");

					//getActionBar().setIcon();
					e.printStackTrace();
				}
				
			}
    }
    
    private class FetchSteamUserImage extends FetchImage {

		public FetchSteamUserImage(String url) {
			super(url.split(".jpg")[0] + "_medium.jpg");
		}
		@SuppressLint("NewApi")
		@Override
		protected void onPostExecute(Bitmap result) {
			super.onPostExecute(result);
			@SuppressWarnings("deprecation")
			Drawable d = new BitmapDrawable(result);
			getActionBar().setIcon(d);
		}
		
	}
    
    private class StartDetailedMatch extends AsyncTask<Void, Void, Intent>{

    	private MatchDetailed matchDetailed;
    	
    	public StartDetailedMatch(MatchDetailed matchDetailed) {
			this.matchDetailed = matchDetailed;
		}
    	
    	@Override
    	protected void onPreExecute() {
			super.onPreExecute();
			
			pDialog = new ProgressDialog(getThisActivity());
	        pDialog.setMessage(getString(R.string.plsWait));
	        pDialog.setIndeterminate(true);
	        pDialog.setCancelable(false);		        
	        pDialog.show();
    	}
    	
		@Override
		protected Intent doInBackground(Void... params) {
			MatchDetailsActivity.setMatch(matchDetailed);

			
			Intent i = new Intent(getThisActivity(), MatchDetailsActivity.class);
			i.putExtra("curAcc", getAccId());
			return i;
		}
		
		@Override
		protected void onPostExecute(Intent result) {
			if(pDialog!=null) {
				pDialog.dismiss();
			}
			startActivity(result);
		}
    	
    }
    
    private class FetchMD extends FetchMatchsDetails {

		public FetchMD(String matchId) {
			super(matchId);
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			
			pDialog = new ProgressDialog(getThisActivity());
	        pDialog.setMessage(getString(R.string.plsWait));
	        pDialog.setIndeterminate(true);
	        pDialog.setCancelable(false);		        
	        pDialog.show();
			
		}
		
		@Override
		protected void onPostExecute(JSONObject result) {
			super.onPostExecute(result);
			
			try {
				MatchDetailed match = new MatchDetailed(result.getJSONObject(Constants.RESULT));
				MatchDetailsActivity.setMatch(match);
				if(pDialog!=null)
				pDialog.dismiss();
				Intent i = new Intent(getApplicationContext(), MatchDetailsActivity.class);
				i.putExtra("curAcc", getAccId());
				startActivity(i);
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
    	
    }
    
    private class FetchDetailedMatchList extends AsyncTask<Void, Integer, Void> {

    	private List<Match> matchsToFetch;
    	private static final String url = "https://api.steampowered.com/IDOTA2Match_570/GetMatchDetails/V001/";
    	private String curAccId;
    	public FetchDetailedMatchList(List<Match> matchId, String curAccId){
    		this.matchsToFetch = matchId;
    		this.curAccId = curAccId;
    	}
    	
    	@Override
    	protected void onPreExecute() {
    	super.onPreExecute();
		pBar.setVisibility(View.VISIBLE);
    	pBar.setMax(matchsToFetch.size());
    	pBar.setProgress(0);
    	}

		@Override
		protected Void doInBackground(Void... nil) {
			int cont = 0;
			for(Match match: matchsToFetch){
				List<NameValuePair> params = new ArrayList<NameValuePair>();
	    		params.add(new BasicNameValuePair(Constants.KEY, Constants.apiKey));
	    		params.add(new BasicNameValuePair(MatchDetailed.TAG_MATCH_ID, match.getMatch_id().toString()));
	    		if(dontStartActivity){
	    		if(MatchDetailed.allMatchsDetailed.get(match.getMatch_id()) == null){
	    			JSONObject json = null;
	    			try {
						InputStream in = openFileInput(match.getMatch_id().toString());
						json = JSONParser.getJsonObjFromInputStream(in);
					} catch (FileNotFoundException e1) {
						json = JSONParser.makeHttpRequest(url, "GET", params);
					}
	    		
					try {
						
						 FileOutputStream outputStream = openFileOutput(match.getMatch_id().toString(), Context.MODE_PRIVATE);						
			    		 outputStream.write(json.toString().getBytes());
			    		 outputStream.close();
			    		 new MatchDetailed(json.getJSONObject(Constants.RESULT));
					} catch (JSONException e) {
						e.printStackTrace();
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
			    } else {
			    	MatchDetailed.allMatchsDetailed.get(match.getMatch_id());
			    }
				runOnUiThread(new Runnable() {
					public void run() {
						matchsAdapter.notifyDataSetChanged();
						try {
							updateStats(curAccId);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});	
	    		}
	    		cont++;
	    		publishProgress(cont);
		}
			
			return null;
		}
		
		@Override
		protected void onProgressUpdate(Integer... values) {
			
			super.onProgressUpdate(values);
			pBar.setProgress(values[0]);
		}
		
		@Override
		protected void onPostExecute(Void result) {
		super.onPostExecute(result);
		pBar.setVisibility(View.INVISIBLE);
		}
		   	
    }
    
    private class FetchMatchs extends Fetch{

		private String accId;
		private long matchIdToStart;
		private int quantity;
	
		
		public FetchMatchs(String accId, long matchIdToStart, int quantity) {
			this.accId = accId;
			this.matchIdToStart = matchIdToStart;
			this.quantity = quantity;
		}
		
		@Override
		protected List<NameValuePair> getParams() {
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			params.add(new BasicNameValuePair(Constants.KEY, Constants.apiKey));
			params.add(new BasicNameValuePair(Constants.ACCID, accId));
			if(matchIdToStart!=0){
				params.add(new BasicNameValuePair("start_at_match_id", String.valueOf(matchIdToStart)));
			}
			if(quantity!=0){
				params.add(new BasicNameValuePair("matches_requested", String.valueOf(quantity)));
			}
			return params;
		}

		@Override
		protected String getUrl() {
			return "https://api.steampowered.com/IDOTA2Match_570/GetMatchHistory/V001/";
		}
		
		@Override
		protected void onPreExecute() {
		super.onPreExecute();
		pDialog = new ProgressDialog(getThisActivity());
        pDialog.setMessage(getString(R.string.plsWait));
        pDialog.setIndeterminate(true);
        pDialog.setCancelable(true);		        
        pDialog.show();
		}
		
		 private void notFoundError(String error){
				if(pDialog!=null)
					  pDialog.dismiss();
			 AlertDialog.Builder builder = new AlertDialog.Builder(getThisActivity());
				builder.setMessage(error)
				       .setCancelable(false)
				       .setPositiveButton("OK", new DialogInterface.OnClickListener() {
				           public void onClick(DialogInterface dialog, int id) {
				             onBackPressed();
				           }
				       });
				AlertDialog alert = builder.create();
				alert.show();
		 }
		
		@Override
		protected void onPostExecute(final JSONObject result) {
			super.onPostExecute(result);

				runOnUiThread(new Runnable() {
					public void run() {
						try {
							JSONObject json = result.getJSONObject(Constants.RESULT);
							if(pDialog!=null)
								  pDialog.dismiss();
							if(json.getInt("status")==1){
							List<Match> newMatchList = Match.getMatchsFromJSONArray(json.getJSONArray(Match.TAG_MATCHES));
							
							List<Match> matchsToFetchDetailed = new ArrayList<Match>();
							
							List<Match> matchsToCheck = new ArrayList<Match>();
							matchsToCheck.addAll(newMatchList);
							if(matchList!=null) {
							matchsToCheck.addAll(matchList);
							}
							for(Match match: matchsToCheck){
								
				    			try {
									InputStream in = openFileInput(match.getMatch_id().toString());
									JSONObject jsonDetailed = JSONParser.getJsonObjFromInputStream(in);
									new MatchDetailed(jsonDetailed.getJSONObject(Constants.RESULT));
								} catch (FileNotFoundException e1) {
									matchsToFetchDetailed.add(match);
								}

							}
							
							if(!matchsToFetchDetailed.isEmpty()){
							new FetchDetailedMatchList(matchsToFetchDetailed, getAccId()).execute();
							}
							setAdapterAndListener(newMatchList);
							} else {
								notFoundError(json.getString("statusDetail"));
							}			


						} catch (JSONException e) {
							
						}
						dontStartActivity = true;
					}
					
				});
			
		}
		
	}
}
